/**
* COPYRIGHT. whx. ALL RIGHTS RESERVED.
* Project: just-core
* Author: whx <harrywu304@gmail.com>
* Create On: Dec 2, 2011 7:45:34 PM
*/

package org.justframework.core.router;

import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import org.justframework.util.HashUtil;

/**
 * ketama consistent hash
 */
public class KetamaRouter<T> implements Router<T> {
	
	private List<T> nodes;
	
	/**
	 * 节点集合
	 */
	protected SortedMap<Long, T> circle = new TreeMap<Long, T>();
	
	/**
	 * 虚拟结点的个数，默认是200
	 */
	private int numberOfReplicas = 200;
	
	public KetamaRouter(){
	}	
	
	/**
	 * 添加节点
	 * @param node
	 */
	private void addNode(T node, String id) {
		for (int i = 0; i < numberOfReplicas; i++) {
			long hash = HashUtil.getKemataHash(id + "_" + i);
			circle.put(hash, node);
		}
	}

	/* (non-Javadoc)
	 * @see org.justframework.core.route.Router#getNodes()
	 */
	public List<T> getNodes() {
		return nodes;
	}

	/* (non-Javadoc)
	 * @see org.justframework.core.route.Router#setNodes(java.util.List)
	 */
	public void setNodes(List<T> nodes) {
		this.nodes = nodes;
		int i =0;
		for (T item : nodes) {
			addNode(item, "n"+i);
			i++;
		}

	}

	/* (non-Javadoc)
	 * @see org.justframework.core.route.Router#locate(java.lang.String)
	 */
	public T locate(String... keys) {
		if (circle.isEmpty()) {
			return null;
		}
		long hash = HashUtil.getKemataHash(keys[0]);
		if (!circle.containsKey(hash)) {
			SortedMap<Long,T> tailMap = circle.tailMap(hash);
			hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
		}
		return circle.get(hash);
	}

}
